In this part, we will perform pathway analysis using the clusterProfiler package, using Overrepresentation Analysis(ORA). We will then visualize the data using various plots such as dotplot, barplot, heatplot or other types of plots(w/ clusterprofiler or ggplot packages).


Prerequisites - DESeq2 analysis and extraction of DEG list

  1. Install and load the necessary libraries
knitr::opts_chunk$set(
 warning = FALSE, message = FALSE
)
#install.packages("BiocManager")
#library(BiocManager)
#BiocManager::install("DESeq2")
#BiocManager::install("apeglm")
#BiocManager::install("tidyverse") # includes ggplot2 and dplyr
#BiocManager::install("EnhancedVolcano")
#install.packages("plotly")
#BiocManager::install("ComplexHeatmap") #alternative = pheatmap
#BiocManager::install( "AnnotationDbi" )
#install.packages("devtools")
#install.packages("Rtools")
#BiocManager::install("EnsDb.Hsapiens.v86")
# BiocManager::install( "clusterProfiler" )
# BiocManager::install( "enrichplot" )
# BiocManager::install("DOSE")
#BiocManager::install("ReactomePA", force = TRUE)
#BiocManager::install("msigdbr", force = TRUE)
#BiocManager::install("KEGGREST", force = TRUE)
# BiocManager::install("BiocUpgrade") ## you may need this
# BiocManager::install("GOSemSim", force = TRUE)
# install.packages("remotes")
# library(devtools)
# devtools::install_github("GuangchuangYu/GOSemSim")
#install.packages(c("ggraph", "ggnetwork")) #altering ggplots 
#devtools::install_github("datapplab/pathview")
#update.packages(c("lattice", "spatial"))
#install.packages("igraph")
#library(DESeq2)
library(AnnotationDbi)
library(devtools)
library(tidyverse) # includes ggplot2, for data visualisation. dplyr, for data manipulation.
library(clusterProfiler) # for PEA analysis
library(org.Hs.eg.db)
library(EnsDb.Hsapiens.v86)
library(DOSE)
library(enrichplot) # for visualisations
library(ggupset) # for visualisations
library(ReactomePA)
library(msigdbr)
library(KEGGREST)
library(httr2)
library(DBI)
library(GOSemSim)
library(lattice)
library(spatial)
library(pathview)
library(cowplot)
library(ggridges)
library(ComplexHeatmap)
library(circlize)
library(igraph)

#Set directory, input and output path
getwd()
## [1] "/home/sant/Downloads/Data Science-bioinformatics learning/Bulk-RNA-seq-analysis-DESeq2/Part 2- Pathway analysis"
in_path <- paste0(getwd(),"/Input/") # input path, where your input data is located
out_path <- paste0(getwd(),"/ORA/") # output path, where you want your results exported to
out_heat <- paste0(getwd(),"/ORA-heatmap/") # output path for heatmap results

2a- Prepare the data for analysis

#Read in the raw gene expression data
df <- read.csv(paste0(in_path, 'DEgenes-sig_ens.csv'), row.names = 1)
#Annotate genes based on differential expression
df <- df %>% mutate(diffexpressed = case_when(
  log2FoldChange > 1 & padj < 0.05 ~ 'UP',
  log2FoldChange < -1 & padj < 0.05 ~ 'DOWN',
  padj > 0.05 ~ 'NO'
))


unique(df$diffexpressed)
## [1] "DOWN" "UP"
na.omit(df)
##Creating a list of up or down DEGs for analysis
# Remove non-significant genes
df_O <- df[df$diffexpressed != 'NO', ]

# Split the dataframe into a list of sub-dataframes: upregulated, downregulated genes
ORA_deg_list <- split(df_O, df_O$diffexpressed)

#saveRDS(ORA_deg_list, file = paste0(in_path,"ORA_deg_list.RDS"))

#Split the genelist into up and down list vectors after converting the IDs to entrez and selecting entrez column

edb <- EnsDb.Hsapiens.v86 #alternative would be org.Hs.eg.db
ORA_up <- bitr(rownames(ORA_deg_list$UP), fromType = "GENEID", toType = "ENTREZID", OrgDb = edb)$ENTREZID

ORA_down <- bitr(rownames(ORA_deg_list$DOWN), fromType = "GENEID", toType = "ENTREZID", OrgDb = edb)$ENTREZID

head(ORA_up)
## [1]   205  1435  4879 23114  5563  2517
head(ORA_down)
## [1] 63967  1031  7398 83540 51514  4751
#save datasets
# write.csv(ORA_up, file = paste0(in_path,"ORA_UP_input.csv"))
# write.csv(ORA_down, file = paste0(in_path,"ORA_DN_input.csv"))

2b- Perform ORA GO analysis and visualization of up or down pathways

##ORA GO analysis#
##up genes##
ego_BP_UP <- enrichGO(ORA_up,
         org.Hs.eg.db,
         keyType = "ENTREZID",
         ont = "BP",
         pvalueCutoff = 0.05,
  pAdjustMethod = "BH")

#Save enrichGO output
# saveRDS(ego_BP_UP, file = paste0(out_path,"GO/ego_BP_UP.RDS"))
# ego_BP_UP <- readRDS(file = "ego_BP_UP.RDS")

#Extract the result table(top 10) and create a new column saying up genes
BP_UP <- as.data.frame(ego_BP_UP@result) %>% 
  slice_head(n = 10) %>%
  mutate(FC = "UP")

slice_head(BP_UP, n =10)
#Save All or top 10 up enrichment results
# write.csv(ego_BP_UP, file = paste0(out_path, "GO/EGO_BP_UP_all.csv"))
# write.csv(BP_UP, file = paste0(out_path, "GO/EGO_BP_UP_top10.csv"))

#goplot Up genes
#pdf(file = paste0(out_path, "GO/EGO_BP.pdf"), width = 10, height = 8, bg = "white")
gpu <- goplot(ego_BP_UP, showCategory = 10)
print(gpu)

#barplot Up genes
#pdf(file = paste0(out_path, "GO/EGO_bar_BP.pdf"), width = 6, height = 6, bg = "white")
bpu <- barplot(ego_BP_UP, showCategory=10, title = "Biological Processes(up)")

print(bpu)

##ORA Down genes##
ego_BP_DN <- enrichGO(ORA_down,
         org.Hs.eg.db,
         keyType = "ENTREZID",
         ont = "BP",
         pvalueCutoff = 0.05,
  pAdjustMethod = "BH")

# Save the RDS file
#saveRDS(ego_BP_DN, file = paste0(out_path,"GO/ego_BP_DN.RDS"))

#Load data from RDS file
#ego_BP_DN <- readRDS("ego_BP_DN.RDS")

#Extract the result table(top 10) and create a new column saying down genes
BP_DN <- ego_BP_DN@result %>% 
  slice_head(n=10) %>%
  mutate(FC = "DOWN")

slice_head(BP_DN, n=10)
#Save All or top 10 down enrichment results
# write.csv(ego_BP_DN, file = paste0(out_path, "GO/EGO_BP_DN_all.csv"))
# write.csv(BP_DN, file = paste0(out_path, "GO/EGO_BP_DN_top10.csv"))

# GO plot down genes
#pdf(file = paste0(out_path, "GO/EGO_BP_DN.pdf"), width = 10, height = 8, bg = "white")
gpd <- goplot(ego_BP_DN, color = "p.adjust", title = "Biological Processes(down") 
print(gpd)

# For barplot:
#pdf(file = paste0(out_path, "GO/EGO_bar_DN.pdf"), width = 6, height = 6, bg = "white")
bpd <- barplot(ego_BP_DN, showCategory=10, fill = "p.adjust", title = "Biological Processes(down)") 

print(bpd)

2c- Combine up and down results then visualize using Barplot and Dotplot

#Combine UP and down results then make GO Plots with ggplot##
#Combine up and down top 10 plots
BP_comb_top10 <- rbind(BP_UP, BP_DN) 

slice_head(BP_comb_top10, n =20)
#save combined data frame
# write.csv(BP_comb_top10, file = paste0(out_path, "GO/GO_BP_top10_combined.csv"))

#import the file
# BP_comb_top10 <- read.csv(file = "GO_BP_top10_combined.csv")

# Create combined ordering column (most robust) for indexing purposes:
BP_comb_top10 <- BP_comb_top10 %>%
  mutate(order_combined = ifelse(FC == "UP", paste0("0_", Description), paste0("1_", Description))) %>% # Add prefix for correct sorting
  arrange(order_combined, -abs(Count)) # Sort by the combined column

# Make counts negative for DOWN-regulated pathways
BP_comb_top10$Count[BP_comb_top10$FC == "DOWN"] <- -BP_comb_top10$Count[BP_comb_top10$FC == "DOWN"]
BP_comb_top10 <- BP_comb_top10 %>% 
  group_by(FC) %>%
      arrange(desc(Count)) %>%
  ungroup()

# 4. Convert Description to factor with correct levels (CRUCIAL):
BP_comb_top10$Description <- factor(BP_comb_top10$Description, levels = rev(unique(BP_comb_top10$Description)))

#Create a ggplot of combined bargraph and save as pdf
#pdf(file = paste0(out_path, "GO/EGO_BP_combo_bar.pdf"), width = 8, height = 6, bg = "white")

GBP <- ggplot(BP_comb_top10, aes(x = Description, y = Count, fill = factor(FC, levels = c("UP", "DOWN")))) +
  geom_col() +
  coord_flip() +
  scale_fill_manual(values = c("UP" = "red", "DOWN" = "blue")) +
  scale_y_continuous(breaks = seq(min(BP_comb_top10$Count), max(BP_comb_top10$Count), by = 25), # Set breaks as needed
                     labels = abs(seq(min(BP_comb_top10$Count), max(BP_comb_top10$Count), by = 25))) + # Show absolute values on axis
  labs(title = "GO BP Pathways", x = NULL, y = "Gene Count", fill = "Fold Change") +
  theme_bw() +
  theme(panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(), axis.text.y = element_text(size = 11), plot.title = element_text(hjust = 0.5)) + geom_hline(yintercept = 0, color = "brown")  # Dashed line

print(GBP)

#Save the Figure object
#saveRDS(GBP, file = paste0(out_path, "GO/EGO_BP_combo_gg.RDS"))

#Repeat the same thing with other ORA analysis(Reactome, Wikipathways...)
#Create dotplots with the top gene lists
#import the corrected geneRatio top10 file
BP_comb_top10 <- read.csv(file = paste0(out_path,"GO/GO_BP_top10_combined.csv"), row.names = 1)

#Function to Split GR and return a ratio
Ratio_GR <- function(y){# Function to separate the gene names in the list, input geneList and Description
  z <- strsplit(y, "/")[[1]] #split and return the geneIds as a vector
  A <- as.numeric(z[1])
  B <- as.numeric(z[2])    
  return(A/B)
  }
BP_comb_top10$GeneRatio <- sapply(BP_comb_top10$GeneRatio, Ratio_GR)  #Ratio changed to numeric and properly

#save
#write.csv(BP_comb_top10, file = paste0(out_path, "GO/BP_top10_correctfinal.csv", row.names = F))

#read in the corrected file
# BP_comb_top10 <- read.csv(file = paste0(out_path,"GO/BP_top10_correctfinal.csv"), row.names = 1)

BP_comb_top10$FC <- factor(BP_comb_top10$FC) 
levels(BP_comb_top10$FC) <- c("UP", "DOWN")

BP_comb_top10 <- BP_comb_top10 %>%
  arrange(-GeneRatio)

#Create ggplot dotplot
#pdf(file = paste0(out_path, "GO/EGO_BP_combo_dot.pdf"), width = 8, height = 6, bg = "white")
dot_BP <- ggplot(BP_comb_top10, aes(x = GeneRatio, y = reorder(Description, GeneRatio), size = Count, color = p.adjust, shape = FC)) +
  geom_point() +
  scale_color_gradient(low = "red", high = "blue") +
  labs(x = "Gene Ratio", y = NULL, size = "Gene Count", shape = "Fold Change", color = "p.adjust", title = "Top GO pathways") +
  theme_bw(base_size = 14, base_line_size = 0.2) +
  theme( plot.title = element_text(hjust = 0.5), axis.text = element_text(size = 13)) +
  guides(shape = guide_legend(override.aes = list(size = 4)))

print(dot_BP)

#Save the Figure object
#saveRDS(dot_BP, file = paste0(out_path, "GO/EGO_BP_combo_dot.RDS"))

2d- Heatplot of GO Up and down results

##Heatplot with GO UP and Down results

#Read the enrichGO results
ego_BP_UP <- readRDS(paste0(out_path,"GO/ego_BP_UP.RDS"))

## convert gene ID to Symbol
edou <- setReadable(ego_BP_UP, edb, 'ENTREZID')

#Read the input geneList with fold change(GSEA input list)
df_RL_E <- read.csv(file = paste0(in_path,"Ranked_ENTREZ_GSEA.csv")) 

#Create a vector with logFC with names as ENTREZ from the gene List
#Function to create geneList with FC vector from unfiltered genes with FC list
geneList_vec_E <- function(x){
  logFC <- x$log2FC
  names(logFC) <- x$ENTREZID
  return(logFC)
}

#Convert genelist into symbol list from entrez and extract into a vector(all unfiltered genes)
#Check keytypes in org.Hs.eg.db- keytypes(org.Hs.eg.db)
geneList_vec_S <- function(x){
  EID <-as.character(x$ENTREZID) #Character vector with ENTREZID for mapping
  x$SYMBOL <-mapIds(edb, keys = EID, keytype = "ENTREZID", column = "SYMBOL", multiVals = "first") 
  logFC <- x$log2FC
  names(logFC) <- x$SYMBOL
  logFC <- logFC[!is.na(names(logFC))]
  return(logFC)
}

geneList_E <- geneList_vec_E(df_RL_E) #Vector with log2FC and ENTREZID as names
geneList_S <- geneList_vec_S(df_RL_E) # Vector with Log2FC and Symbol as names

#write.csv(geneList_S, file = paste0(in_path, "Ranked_ENTREZ_GSEA_Symbol.csv"), row.names = F) #Save the ranked genelist with symbols
slice_head(edou@result, n=10)
#heatplot of up genes
p7 <- heatplot(edou, foldChange=geneList_S, symbol = "dot", showCategory=5) + viridis::scale_fill_viridis(name = "log2FC") + ggtitle("Upregulated") + theme(plot.title = element_text(hjust = 0.5, vjust = -3))


##Heatplot with GO Down results###
#Read the enrichGO results and convert it to gene symbols
ego_BP_DN <- readRDS(paste0(out_path,"GO/ego_BP_DN.RDS"))

## convert gene ID to Symbol
edox <- setReadable(ego_BP_DN, edb, 'ENTREZID')

slice_head(edox@result, n=10)
#Heatplot of down genes
p8 <- heatplot(edox, foldChange=geneList_S, symbol = "dot", showCategory=5) + viridis::scale_fill_viridis(name = "log2FC") + ggtitle("Downregulated") + theme(plot.title = element_text(hjust = 0.5, vjust = -3))


#Visualize and save both up and down heatplot figures
#pdf(file = paste0(out_path, "GO/EGO_BP_heatplot_combo.pdf"), width = 36, height = 14, bg = "white")
combo <- cowplot::plot_grid(p7,p8, ncol=1, labels=letters[1:2])
print(combo)

3- Additional plots(cnet, emap, treeplot)

#cnet analysis - interaction network
#Import unfiltered genelist vector with logFC 
#Read the enrichGO results and convert it to gene symbols
#ego_BP_DN <- readRDS("ego_BP_DN.RDS")

## convert gene ID to Symbol
#edox <- setReadable(ego_BP_DN, edb, 'ENTREZID')

#Up genes
## categorySize can be scaled by 'pvalue' or 'geneNum'
p1 <- cnetplot(edou, categorySize="pvalue", foldChange=geneList_S) + ggtitle("Upregulated") + theme(plot.title = element_text(hjust = 0.5))
p2 <- cnetplot(edou, foldChange=geneList_S, igraph::layout_in_circle, showCategory = 2, colorEdge = TRUE) + ggtitle("Upregulated") + theme(plot.title = element_text(hjust = 0.5))

#Down genes
## categorySize can be scaled by 'pvalue' or 'geneNum'
p3 <- cnetplot(edox, categorySize="pvalue", foldChange=geneList_S) + ggtitle("Downregulated") + theme(plot.title = element_text(hjust = 0.5))
p4 <- cnetplot(edox, foldChange=geneList_S, igraph::layout_in_circle, showCategory = 2, colorEdge = TRUE) + ggtitle("Downregulated") + theme(plot.title = element_text(hjust = 0.5))

#Save the combined up and down cnet plots
#pdf(file = paste0(out_path, "GO/EGO_BP_cnet_up or down.pdf"), width = 25, height = 30, bg = "white")
cn <- cowplot::plot_grid(p1, p3, p2, p4, ncol=2, labels=LETTERS[1:4])
print(cn)

#enrichment map
#Up genes
edou3 <- pairwise_termsim(edou)
pe1 <- emapplot(edou3) + theme(plot.margin = margin(2,2,2,2)) + ggtitle("Upregulated") + theme(plot.title = element_text(hjust = 0.5))

#Down genes
edox3 <- pairwise_termsim(edox)
pe2 <- emapplot(edox3) + theme(plot.margin = margin(2,2,2,2)) + ggtitle("Downregulated") + theme(plot.title = element_text(hjust = 0.5))

#pdf(file = paste0(out_path, "GO/EGO_BP_emap_up or down.pdf"), width = 16, height = 7, bg = "white")
ep <- cowplot::plot_grid(pe1, pe2, ncol=2, labels=letters[1:2], rel_widths = c(0.5, 0.5))

print(ep)

#Treeplot

#Up and down genes
edox2 <- pairwise_termsim(edox)
edou2 <- pairwise_termsim(edou)

pt1 <- treeplot(edox2, foldChange = geneList_S, hclust_method = "average") + ggtitle("Downregulated") + theme(plot.title = element_text(hjust = 0.3, vjust = -1))
pt2 <- treeplot(edou2, foldChange = geneList_S, hclust_method = "average") + ggtitle("Upregulated") + theme(plot.title = element_text(hjust = 0.3, vjust = -1))

# pdf(file = paste0(out_path, "GO/EGO_BP_tree_up or down_A.pdf"), width = 22, height = 18, bg = "white")
# tpa <- aplot::plot_list(pt2, pt1, tag_levels='a')
# print(tpa)
# 

#pdf(file = paste0(out_path, "GO/EGO_BP_tree_up or down.pdf"), width = 16, height = 18, bg = "white")
tp <- cowplot::plot_grid(pt2, pt1, ncol=1, labels=letters[1:2], rel_widths = c(0.5, 0.5))
print(tp)

sessionInfo() 
## R version 4.4.3 (2025-02-28)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 24.04.2 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.12.0 
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## time zone: America/Chicago
## tzcode source: system (glibc)
## 
## attached base packages:
## [1] grid      stats4    stats     graphics  grDevices utils     datasets 
## [8] methods   base     
## 
## other attached packages:
##  [1] igraph_2.1.4              circlize_0.4.16          
##  [3] ComplexHeatmap_2.22.0     ggridges_0.5.6           
##  [5] cowplot_1.1.3             pathview_1.43.1          
##  [7] spatial_7.3-17            lattice_0.22-5           
##  [9] GOSemSim_2.33.0           DBI_1.2.3                
## [11] httr2_1.1.0               KEGGREST_1.46.0          
## [13] msigdbr_7.5.1             ReactomePA_1.50.0        
## [15] ggupset_0.4.1             enrichplot_1.26.6        
## [17] DOSE_4.0.0                EnsDb.Hsapiens.v86_2.99.0
## [19] ensembldb_2.30.0          AnnotationFilter_1.30.0  
## [21] GenomicFeatures_1.58.0    GenomicRanges_1.58.0     
## [23] GenomeInfoDb_1.42.3       org.Hs.eg.db_3.20.0      
## [25] clusterProfiler_4.14.4    lubridate_1.9.4          
## [27] forcats_1.0.0             stringr_1.5.1            
## [29] dplyr_1.1.4               purrr_1.0.4              
## [31] readr_2.1.5               tidyr_1.3.1              
## [33] tibble_3.2.1              ggplot2_3.5.1            
## [35] tidyverse_2.0.0           devtools_2.4.5           
## [37] usethis_3.1.0             AnnotationDbi_1.68.0     
## [39] IRanges_2.40.1            S4Vectors_0.44.0         
## [41] Biobase_2.66.0            BiocGenerics_0.52.0      
## 
## loaded via a namespace (and not attached):
##   [1] splines_4.4.3               later_1.4.1                
##   [3] BiocIO_1.16.0               bitops_1.0-9               
##   [5] ggplotify_0.1.2             R.oo_1.27.0                
##   [7] polyclip_1.10-7             graph_1.84.1               
##   [9] XML_3.99-0.18               lifecycle_1.0.4            
##  [11] doParallel_1.0.17           MASS_7.3-64                
##  [13] magrittr_2.0.3              sass_0.4.9                 
##  [15] rmarkdown_2.29              jquerylib_0.1.4            
##  [17] yaml_2.3.10                 remotes_2.5.0              
##  [19] httpuv_1.6.15               ggtangle_0.0.6             
##  [21] sessioninfo_1.2.3           pkgbuild_1.4.6             
##  [23] RColorBrewer_1.1-3          abind_1.4-8                
##  [25] pkgload_1.4.0               zlibbioc_1.52.0            
##  [27] R.utils_2.12.3              ggraph_2.2.1               
##  [29] RCurl_1.98-1.16             yulab.utils_0.2.0          
##  [31] rappdirs_0.3.3              tweenr_2.0.3               
##  [33] GenomeInfoDbData_1.2.13     ggrepel_0.9.6              
##  [35] tidytree_0.4.6              reactome.db_1.89.0         
##  [37] codetools_0.2-20            DelayedArray_0.32.0        
##  [39] ggforce_0.4.2               shape_1.4.6.1              
##  [41] tidyselect_1.2.1            aplot_0.2.4                
##  [43] UCSC.utils_1.2.0            farver_2.1.2               
##  [45] viridis_0.6.5               matrixStats_1.5.0          
##  [47] GenomicAlignments_1.42.0    jsonlite_1.8.9             
##  [49] GetoptLong_1.0.5            ellipsis_0.3.2             
##  [51] tidygraph_1.3.1             iterators_1.0.14           
##  [53] foreach_1.5.2               ggnewscale_0.5.0           
##  [55] tools_4.4.3                 treeio_1.30.0              
##  [57] Rcpp_1.0.14                 glue_1.8.0                 
##  [59] gridExtra_2.3               SparseArray_1.6.1          
##  [61] xfun_0.50                   qvalue_2.38.0              
##  [63] MatrixGenerics_1.18.1       withr_3.0.2                
##  [65] fastmap_1.2.0               digest_0.6.37              
##  [67] timechange_0.3.0            R6_2.6.1                   
##  [69] mime_0.12                   gridGraphics_0.5-1         
##  [71] colorspace_2.1-1            GO.db_3.20.0               
##  [73] RSQLite_2.3.9               R.methodsS3_1.8.2          
##  [75] generics_0.1.3              data.table_1.16.4          
##  [77] rtracklayer_1.66.0          graphlayouts_1.2.2         
##  [79] httr_1.4.7                  htmlwidgets_1.6.4          
##  [81] S4Arrays_1.6.0              graphite_1.52.0            
##  [83] pkgconfig_2.0.3             gtable_0.3.6               
##  [85] blob_1.2.4                  XVector_0.46.0             
##  [87] htmltools_0.5.8.1           profvis_0.4.0              
##  [89] fgsea_1.32.2                clue_0.3-66                
##  [91] ProtGenerics_1.38.0         scales_1.3.0               
##  [93] png_0.1-8                   ggfun_0.1.8                
##  [95] knitr_1.49                  rstudioapi_0.17.1          
##  [97] tzdb_0.4.0                  reshape2_1.4.4             
##  [99] rjson_0.2.23                nlme_3.1-167               
## [101] curl_6.2.0                  GlobalOptions_0.1.2        
## [103] cachem_1.1.0                ggarchery_0.4.3            
## [105] parallel_4.4.3              miniUI_0.1.1.1             
## [107] restfulr_0.0.15             pillar_1.10.1              
## [109] vctrs_0.6.5                 urlchecker_1.0.1           
## [111] promises_1.3.2              cluster_2.1.8              
## [113] xtable_1.8-4                Rgraphviz_2.50.0           
## [115] KEGGgraph_1.66.0            evaluate_1.0.3             
## [117] cli_3.6.4                   compiler_4.4.3             
## [119] Rsamtools_2.22.0            rlang_1.1.5                
## [121] crayon_1.5.3                labeling_0.4.3             
## [123] plyr_1.8.9                  fs_1.6.5                   
## [125] stringi_1.8.4               viridisLite_0.4.2          
## [127] BiocParallel_1.40.0         babelgene_22.9             
## [129] munsell_0.5.1               Biostrings_2.74.1          
## [131] lazyeval_0.2.2              Matrix_1.7-2               
## [133] hms_1.1.3                   patchwork_1.3.0            
## [135] bit64_4.6.0-1               shiny_1.10.0               
## [137] SummarizedExperiment_1.36.0 memoise_2.0.1              
## [139] bslib_0.9.0                 ggtree_3.14.0              
## [141] fastmatch_1.1-6             bit_4.5.0.1                
## [143] ape_5.8-1                   gson_0.1.0